<?php

namespace app\oauth\controller;

use app\oauth\BaseController;
use think\facade\View;
use app\model\User as UserModel;
use app\model\Access as AccessModel;

class Callback extends BaseController
{
    public function index()
    {
        $plat = strtolower(input('plat'));
        if (!$plat) {
            return redirect('/oauth');
        }
        $code = input('code');;
        if (!$code) {
            return redirect('/oauth');
        }
        $redirect_uri = urlencode(getFullDomain() . "/oauth/callback?plat=" . $plat);
        $oauthList = getOauthConfig();
        switch ($plat) {
            case  'gitee':
                $url = "https://gitee.com/oauth/token?grant_type=authorization_code&code={$code}&client_id=" . $oauthList[$plat]['id'] . "&redirect_uri={$redirect_uri}&client_secret=" . $oauthList[$plat]['key'] . "";
                $result = curlHelper($url, 'POST', [], [], "");
                if ($result['detail']['http_code'] == 200) {
                    $obj = json_decode($result['body'], true);
                    $access_token = $obj['access_token'];
                    $url = "https://gitee.com/api/v5/user?access_token={$access_token}";
                    $result = curlHelper($url);
                    if ($result['detail']['http_code'] == 200) {
                        $user = json_decode($result['body'], true);
                        $user = ['id' => $user['id'], 'avatar_url' => $user['avatar_url'], 'login' => $user['login'], 'name' => $user['name'], 'plat' => '码云'];
                        $access = $this->userLogin($user, $plat);
                        cookie('access_token', $access['access_token']);
                    }
                }
                break;
            case  'oschina':
                $url = "https://www.oschina.net/action/openapi/token?grant_type=authorization_code&code={$code}&client_id=" . $oauthList[$plat]['id'] . "&redirect_uri={$redirect_uri}&client_secret=" . $oauthList[$plat]['key'] . "";
                $result = curlHelper($url, 'POST', [], [], "");
                if ($result['detail']['http_code'] == 200) {
                    $obj = json_decode($result['body'], true);
                    $access_token = $obj['access_token'];
                    $url = "https://www.oschina.net/action/openapi/user?access_token={$access_token}";
                    $result = curlHelper($url);
                    if ($result['detail']['http_code'] == 200) {
                        $user = json_decode($result['body'], true);
                        $user = ['id' => $user['id'], 'avatar_url' => explode('!', $user['avatar'])[0], 'login' => str_replace('https://my.oschina.net/', '', $user['url']), 'name' => $user['name'], 'plat' => '开源中国'];
                        $access = $this->userLogin($user, $plat);
                        cookie('access_token', $access['access_token']);
                    }
                }
                break;
            case  'qq':
                $redirect_uri = urlencode(getFullDomain() . "/callback.php?plat=" . $plat);
                $url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&code={$code}&client_id=" . $oauthList[$plat]['id'] . "&redirect_uri={$redirect_uri}&client_secret=" . $oauthList['qq']['key'] . "";
                $result = curlHelper($url);
                if ($result['detail']['http_code'] == 200) {
                    if (preg_match('/access_token=(.*?)&/', $result['body'], $match)) {
                        $access_token = $match[1];
                        $url = "https://graph.qq.com/oauth2.0/me?access_token={$access_token}";
                        $result = curlHelper($url);
                        if ($result['detail']['http_code'] == 200) {
                            if (preg_match('/openid":"(.*?)"/', $result['body'], $match)) {
                                $openid = $match[1];
                                $url = "https://graph.qq.com/user/get_user_info?access_token={$access_token}&openid={$openid}&oauth_consumer_key=" . $oauthList[$plat]['id'];
                                $result = curlHelper($url);
                                $user = json_decode($result['body'], true);
                                if ($user['ret'] == 0) {
                                    $user = ['id' => $openid, 'avatar_url' => $user['figureurl_qq_2'] ?? $user['figureurl_qq_1'], 'login' => $openid, 'name' => $user['nickname'], 'plat' => 'QQ'];
                                    $access = $this->userLogin($user, $plat);
                                    cookie('access_token', $access['access_token']);
                                }
                            }
                        }
                    }
                }
                break;
            case  'github':
                $url = "https://github.com/login/oauth/access_token?code={$code}&client_id=" . $oauthList[$plat]['id'] . "&redirect_uri={$redirect_uri}&client_secret=" . $oauthList[$plat]['key'] . "";
                $result = curlHelper($url);
                if (preg_match('/access_token=(.*?)&/', $result['body'], $match)) {
                    $access_token = $match[1];
                    $url = "https://api.github.com/user?access_token={$access_token}";
                    $result = curlHelper($url, 'GET', [], ["User-Agent: HammCn", 'Accept: application/json']);
                    if ($result['detail']['http_code'] == 200) {
                        $user = json_decode($result['body'], true);
                        $user = ['id' => $user['id'], 'avatar_url' => '/github.png', 'login' => $user['login'], 'name' => $user['name'], 'plat' => 'Github'];
                        $access = $this->userLogin($user, $plat);
                        cookie('access_token', $access['access_token']);
                    } else {
                        echo 'Faild to get userinfo from Github.<a href="/oauth">Retry it!</a>';
                        die;
                    }
                }
                break;
            default:
                die('Error plat');
                break;
        }
        return redirect('/');
    }
    protected function userLogin($userInfo, $plat)
    {
        $userModel = new UserModel();
        $account = sha1($userInfo['id'] . 'BBBUG.COM' . $plat);
        $user = $userModel->getUserByAccount($account);
        if (!$user) {
            $salt = 'Hamm';
            $userModel->insert([
                "user_account" => $account,
                "user_password" => encodePassword('123456', $salt),
                "user_salt" => $salt,
                "user_plat" => $plat,
                "user_head" => $userInfo['avatar_url'],
                "user_login" => $userInfo['login'],
                "user_name" => urlencode($userInfo['name']),
                "user_group" => 5,
                "user_ipreg" => request()->ip(),
                "user_createtime" => time(),
                "user_updatetime" => time()
            ]);
        } else {
            $userModel->where("user_id", $user['user_id'])->update([
                "user_head" => $userInfo['avatar_url'],
                "user_login" => $userInfo['login'],
                "user_name" => urlencode($userInfo['name']),
                "user_updatetime" => time()
            ]);
        }
        $user = $userModel->getUserByAccount($account);
        $accessModel = new AccessModel();
        $access = $accessModel->createAccess($user['user_id'], $plat);
        return $access;
    }
}
